package com.hmagic.hbase.core;

import com.jfinal.kit.PropKit;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Table;
import org.apache.log4j.Logger;

import java.io.IOException;

/**
 *  hbase连接池
 *
 *  @author  shengshi_feiyang@yeah.net
 *  @version  2017-03-01
 */
public class ConnectionPool {

     Logger logger = Logger.getLogger(ConnectionPool.class);

     private int maxTotal = 10;//最大链接数

     private int maxIdle = 6;//最大空闲数

     private int minIdle = 3; //最小空闲数


     private static ConnectionPool connectionPool = null;

     private static GenericObjectPool<Connection> genericObjectPool = null;


    public static ConnectionPool  getInstance(){
        if(null == connectionPool){
            connectionPool = new ConnectionPool();
        }
        return connectionPool;
    }

    public Connection getConnection()  {
        Connection connection = null;
        try {
            connection = genericObjectPool.borrowObject();
        } catch (Exception e) {
            logger.error("获取链接失败:"+e.getMessage());
            e.printStackTrace();
        }
        return  connection;
    }

    public void returnConnection(Connection connection){
        genericObjectPool.returnObject(connection);
    }

    public  GenericObjectPool<Connection> getGenericObjectPool(){
        return genericObjectPool;
    }

    public static  void main(String arg0[]){
        ConnectionPool connectionPool = ConnectionPool.getInstance();
        GenericObjectPool<Connection> objectPool = connectionPool.getGenericObjectPool();

        System.out.println("池子容量："+objectPool.getMaxTotal());
        System.out.println("最大空闲："+objectPool.getMaxIdle());
        System.out.println("最小空闲："+objectPool.getMinIdle());


        System.out.println("使用的："+objectPool.getNumActive());
        System.out.println("实例化的："+objectPool.getNumIdle());

        Connection connection = connectionPool.getConnection();
        try {
            Table table = connection.getTable(TableName.valueOf("news:news_content"));
            System.out.println("表名称:" + table.getName());

        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            Thread.sleep(60*60*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private ConnectionPool(){
        initConfig();//初始化配置

        initPool();//初始化池子
    }

    /**
     * 实例化池子
     */
    private  void initPool(){
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxTotal(maxTotal);
        poolConfig.setMinIdle(minIdle);
        poolConfig.setMaxTotal(maxIdle);
        genericObjectPool = new GenericObjectPool(new ConnectionPoolFactory(), poolConfig);
    }

    /**
     * 初始化配置
     */
    private void initConfig(){
        PropKit.use("config.properties");
        this.maxTotal = PropKit.getInt("hbase.maxTotal", 10);
        this.maxIdle = PropKit.getInt("hbase.maxIdle",6);
        this.minIdle = PropKit.getInt("hbase.minIdle",2);
    }

    public int getMaxTotal() {
        return maxTotal;
    }

    public int getMaxIdle() {
        return maxIdle;
    }

    public int getMinIdle() {
        return minIdle;
    }


    /**
     *  HBase连接工厂
     */
    class ConnectionPoolFactory extends BasePooledObjectFactory<Connection> {

        Logger logger = Logger.getLogger(ConnectionPoolFactory.class);

        @Override
        public Connection create() throws Exception {
            Connection connection = null;
            Configuration conf = HBaseConfiguration.create();
            try {
                connection = ConnectionFactory.createConnection(conf);
            } catch (IOException e) {
                logger.error("创建Hbase链接失败:"+e.getMessage());
                e.printStackTrace();
            }
            return connection;
        }

        @Override
        public PooledObject<Connection> wrap(Connection connection) {
            return new DefaultPooledObject<Connection>(connection);
        }

    }


}
